{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "5QoWip9KktQ0"
      },
      "outputs": [],
      "source": [
        "\"\"\"Licensed under the Apache License, Version 2.0.\"\"\"\n",
        "\n",
        "# Note due to random number generation in the underlying libraries, most notably \n",
        "# networkx, there are slight differences between results from running this colab\n",
        "# and those seen in the manuscript.\n",
        "\n",
        "import os\n",
        "import matplotlib.pyplot as plt\n",
        "import seaborn as sns\n",
        "import numpy as np\n",
        "import pandas as pd\n",
        "\n",
        "from IPython import display\n",
        "\n",
        "import plotnine as p9\n",
        "\n",
        "# Library of analysis code common to experiments.\n",
        "import protseq_analysis"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "6uH0Q314F_YL"
      },
      "outputs": [],
      "source": [
        "# Download the dataset from:\n",
        "# Jess, Phillip (2021), “ProtSeq Data”, Mendeley Data, V1, doi: 10.17632/f9hdn5xc3v.1\n",
        "# https://data.mendeley.com/datasets/f9hdn5xc3v/1\n",
        "\n",
        "!wget https://data.mendeley.com/public-files/datasets/f9hdn5xc3v/files/3590fc8d-f47e-4199-982a-45871305178e/file_downloaded -O \"Six cycle DNA_DNA BCS base calls.fastq.gz\"\n",
        "!wget https://data.mendeley.com/public-files/datasets/f9hdn5xc3v/files/ae9dfef2-af3f-4592-a895-519b8013f6c8/file_downloaded -O \"Six cycle DNA_DNA BCS undertermined calls.fastq.gz\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "82oAwAANfj1x"
      },
      "outputs": [],
      "source": [
        "FEATURE_DELIM = ':'\n",
        "TAG_PREFIX = 'S_'\n",
        "MATCH_STR = 'SA'"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "1nyn2171wDJ8"
      },
      "outputs": [],
      "source": [
        "expt_dict = {\n",
        "    'base': ['Six cycle DNA_DNA BCS base calls.fastq.gz'],\n",
        "    'undertermined': ['Six cycle DNA_DNA BCS undertermined calls.fastq.gz'],\n",
        "}\n",
        "\n",
        "DNA_BINDER_DICT = {'SP12':'SA12', 'SP11':'SA11', 'SP10':'SA10', 'SP13':'SA13'} # These are the three standard DNA:DNA binder/target pairs. Update if new DNA:DNA binders are used\n",
        "\n",
        "component_names_str = '''\n",
        "BCS_Fd1_SP12\tAACAC\n",
        "BCS_Fd2_SP10\tTCACA\n",
        "BCS_Fd3_SP11\tTTCAG\n",
        "BCS_Fd7_NULL\tATCAAGGC\n",
        "BCS_Fd8_SP13\tCTAGTACG\n",
        "BCS.SA10-1\tTACCAAGA\n",
        "BCS.SA11-1\tTGAGTATC\n",
        "BCS.SA12-1\tGCTGTTCA\n",
        "BCS.SA5_Random-1\tTGAGCCTT\n",
        "BCS.SA13-1\tTTCGTAAC\n",
        "BCS.SA10-2\tTGTATAGT\n",
        "BCS.SA11-2\tAGGGTAAT\n",
        "BCS.SA12-2\tTTCACCAG\n",
        "BCS.SA5_Random-2\tAAATCGGA\n",
        "BCS.SA13-2\tTGATACGA\n",
        "BCS.SA10-3\tTGAACTTG\n",
        "BCS.SA11-3\tACTTTACC\n",
        "BCS.SA12-3\tATCTGAGC\n",
        "BCS.SA5_Random-3\tGGTCTCTA\n",
        "BCS.SA13-3\tCCTTCATA\n",
        "BCS.SA10-4\tTAGTCCAC\n",
        "BCS.SA11-4\tGCCATATA\n",
        "BCS.SA12-4\tCCTCTCAT\n",
        "BCS.SA5-4\tGGCTATAG\n",
        "BCS.SA13-4\tGGAATCAA\n",
        "BCS.SA10-5\tCACGAAAT\n",
        "BCS.SA11-5\tTCTTTCTA\n",
        "BCS.SA12-5\tATGAGAAG\n",
        "BCS.SA5-5\tATTCGATG\n",
        "BCS.SA13-5\tATAGTCCT\n",
        "BCS.SA10-6\tACTTACAC\n",
        "BCS.SA11-6\tTGACTAGT\n",
        "BCS.SA12-6\tGGTCGTTA\n",
        "BCS.SA5-6\tTTCTATCC\n",
        "BCS.SA13-6\tTTCAAACA\n",
        "BCS.SA_Null\tTACCATGG\n",
        "BCS4_DirectSeqSA_BC\tAGACTCAG\n",
        "BCS4_DirectSeqSA_Missed\tCTGCGCCTATACGAATT\n",
        "NGS_Adapt\tGTATG\n",
        "BS_Bridge\tCGTTATC\n",
        "BS_Base\tCATCAGCTCGCAGTCG\n",
        "'''\n",
        "subseqs, component_dict, seq_rev_comp_dict = protseq_analysis.get_subseqs_from_component_names(component_names_str)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "XFUFdV80R-eB"
      },
      "outputs": [],
      "source": [
        "foundation_dict = {}\n",
        "non_Fd_components = [component for component in component_dict.values() if protseq_analysis.FOUNDATION_SUBSTR not in component]\n",
        "\n",
        "for component in component_dict.values():\n",
        "  if protseq_analysis.FOUNDATION_SUBSTR in component:\n",
        "    binder_match_unit = component.split('_')[-1]\n",
        "    if binder_match_unit == 'NULL':\n",
        "      continue\n",
        "    binder_match_str = '.' + DNA_BINDER_DICT[binder_match_unit]\n",
        "    foundation_dict[component] = [non_fd_comp for non_fd_comp in non_Fd_components if (binder_match_str in non_fd_comp)]\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "8Am6GhSqpQlm"
      },
      "outputs": [],
      "source": [
        "SEQS_TO_READ = 100000000 # Number of sequences\n",
        "DIST_FOR_CLUSTERING = 0\n",
        "N_COMMON = 50000000\n",
        "full_df = protseq_analysis.read_fastqs_for_experiment(\n",
        "    expt_dict, num_reads=SEQS_TO_READ, subseqs=subseqs, n_common=N_COMMON, \n",
        "    dist_for_clustering=DIST_FOR_CLUSTERING)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "nxZp8Tb1Bv2p"
      },
      "outputs": [],
      "source": [
        "cycle_dfs, cycle_correspondence = protseq_analysis.foundation_partner_cycle_table(full_df, foundation_dict,\n",
        "                                                         component_dict, cycles_to_check=6, heatmap=False,\n",
        "                                                         allow_overlaps=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lHL89UNR_k_X"
      },
      "source": [
        "##Plotting and Tables"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "DPCuryPS_mwW"
      },
      "source": [
        "## Produce stacked histogram and counts table"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "height": 623
        },
        "executionInfo": {
          "elapsed": 3775,
          "status": "ok",
          "timestamp": 1632435367005,
          "user": {
            "displayName": "",
            "photoUrl": "",
            "userId": ""
          },
          "user_tz": 420
        },
        "id": "TL5SBWA9Fpvo",
        "outputId": "22ba4fb8-fd21-46e6-a33b-91f2c1ef54a8"
      },
      "outputs": [
        {
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "\u003cFigure size 640x480 with 4 Axes\u003e"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "image/png": "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\nYII=\n",
            "text/plain": [
              "\u003cFigure size 200x400 with 1 Axes\u003e"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "def convert_cycle_dfs_to_stacked_hists(cycle_dfs, foundation_dict, \n",
        "                                      min_cycle, max_cycle):\n",
        "  ''' Generate stacked histograms figures figures for multi-cycle runs.'''\n",
        "  \n",
        "  # Generate dataframe based on expected cycle\n",
        "  foundations = []\n",
        "  aptamers = []\n",
        "  counts = []\n",
        "  exp_cycles = []\n",
        "  matches = []\n",
        "  for i in range (min_cycle, max_cycle+1):\n",
        "    cycle_df = cycle_dfs[i]\n",
        "    for col in cycle_df.columns:\n",
        "      for key, values in foundation_dict.items():\n",
        "        aptamer = key.split('_')[-1]\n",
        "        for val in values:\n",
        "          # Tag association foundation target with corresponding aptamer\n",
        "          tag = col.split('_')[-1]\n",
        "          foundations.append(tag)\n",
        "          aptamers.append(aptamer)\n",
        "          exp_cycle = int(val[-1])\n",
        "          count = cycle_df[col].loc[val]\n",
        "          exp_cycles.append(exp_cycle)\n",
        "          counts.append(count)\n",
        "          matches.append(tag == aptamer)\n",
        "\n",
        "  exp_plot_df = pd.DataFrame.from_dict({'Fd': foundations,\n",
        "                          'aptamer': aptamers,\n",
        "                          'count': counts,\n",
        "                          'exp_cycle': exp_cycles,\n",
        "                          'match': matches,})\n",
        "  \n",
        "  exp_plot_agg_df = exp_plot_df.groupby(\n",
        "      ['Fd', 'aptamer', 'exp_cycle', 'match']).sum().reset_index()\n",
        "\n",
        "  p = (p9.ggplot(exp_plot_agg_df[exp_plot_agg_df['Fd'] != 'Foundation'], \n",
        "                p9.aes('exp_cycle', 'count', fill='match')) + \n",
        "      p9.geom_bar(stat='identity', position='stack') + p9.facet_wrap('~Fd') +\n",
        "        p9.theme_minimal())\n",
        "                \n",
        "  p.draw()\n",
        "\n",
        "  # Generate dataframe based on \"observed\" cycle  \n",
        "  foundations = []\n",
        "  matches = []\n",
        "  aptamers = []\n",
        "  counts = []\n",
        "  cycles = []\n",
        "  for i in range (min_cycle, max_cycle+1):\n",
        "    cycle_df = cycle_dfs[i]\n",
        "    for col in cycle_df.columns:\n",
        "      for key, values in foundation_dict.items():\n",
        "        cycle_matches = [val for val in values if int(val[-1]) == i]\n",
        "        cycle_mismatches =  [val for val in values if int(val[-1]) != i]\n",
        "        aptamer = key.split('_')[-1]\n",
        "\n",
        "        # Set placeholders to allow for two rows:\n",
        "        #   1. Calculate when the expected cycle matches observed cycle\n",
        "        #   2. Calculate when expected cycle mismatches observed cycle\n",
        "        foundations += [col.split('_')[-1]]*2\n",
        "        aptamers += [aptamer]*2\n",
        "        cycles += [i]*2  \n",
        "        \n",
        "        # Add in match/mismatch flags and counts.\n",
        "        matches += [True]\n",
        "        matches += [False]\n",
        "        counts += [cycle_df[col].loc[cycle_matches].sum()]\n",
        "        counts += [cycle_df[col].loc[cycle_mismatches].sum()]\n",
        "          \n",
        "  plot_df = pd.DataFrame.from_dict({'Fd': foundations,\n",
        "                          'match': matches,\n",
        "                          'aptamer': aptamers,\n",
        "                          'count': counts,\n",
        "                          'cycle': cycles})\n",
        "  \n",
        "  # Aggregate based on 'Fd' and 'aptamer'\n",
        "  # This ignores cycle information and corresponding matching cycle information.\n",
        "  plot_agg_df = plot_df.groupby(['Fd', 'aptamer']).sum()[['count']].reset_index()\n",
        "\n",
        "  p = (p9.ggplot(plot_agg_df[plot_agg_df['Fd'] != 'Foundation'], \n",
        "                 p9.aes('Fd', 'count', fill='aptamer')) + \n",
        "                 p9.geom_bar(stat='identity', position='stack') +\n",
        "        p9.theme_minimal() + p9.theme(figure_size=[2, 4]))\n",
        "                 \n",
        "  p.draw()   \n",
        "\n",
        "  return exp_plot_agg_df\n",
        "        \n",
        "exp_plot_agg_df = convert_cycle_dfs_to_stacked_hists(cycle_dfs, foundation_dict, 1, 6)\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "height": 833
        },
        "executionInfo": {
          "elapsed": 59,
          "status": "ok",
          "timestamp": 1632435367211,
          "user": {
            "displayName": "",
            "photoUrl": "",
            "userId": ""
          },
          "user_tz": 420
        },
        "id": "BGncsGdixqyM",
        "outputId": "c0542d63-6471-4f90-d4da-cc069dbdecb4"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\u003cdiv\u003e\n",
              "\u003cstyle scoped\u003e\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "\u003c/style\u003e\n",
              "\u003ctable border=\"1\" class=\"dataframe\"\u003e\n",
              "  \u003cthead\u003e\n",
              "    \u003ctr style=\"text-align: right;\"\u003e\n",
              "      \u003cth\u003e\u003c/th\u003e\n",
              "      \u003cth\u003eFd\u003c/th\u003e\n",
              "      \u003cth\u003eSP10\u003c/th\u003e\n",
              "      \u003cth\u003eSP11\u003c/th\u003e\n",
              "      \u003cth\u003eSP12\u003c/th\u003e\n",
              "      \u003cth\u003eSP13\u003c/th\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003eaptamer\u003c/th\u003e\n",
              "      \u003cth\u003eexp_cycle\u003c/th\u003e\n",
              "      \u003cth\u003e\u003c/th\u003e\n",
              "      \u003cth\u003e\u003c/th\u003e\n",
              "      \u003cth\u003e\u003c/th\u003e\n",
              "      \u003cth\u003e\u003c/th\u003e\n",
              "    \u003c/tr\u003e\n",
              "  \u003c/thead\u003e\n",
              "  \u003ctbody\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth rowspan=\"6\" valign=\"top\"\u003eSP10\u003c/th\u003e\n",
              "      \u003cth\u003e1\u003c/th\u003e\n",
              "      \u003ctd\u003e6539\u003c/td\u003e\n",
              "      \u003ctd\u003e2096\u003c/td\u003e\n",
              "      \u003ctd\u003e1009\u003c/td\u003e\n",
              "      \u003ctd\u003e885\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e2\u003c/th\u003e\n",
              "      \u003ctd\u003e8833\u003c/td\u003e\n",
              "      \u003ctd\u003e116\u003c/td\u003e\n",
              "      \u003ctd\u003e347\u003c/td\u003e\n",
              "      \u003ctd\u003e107\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e3\u003c/th\u003e\n",
              "      \u003ctd\u003e11316\u003c/td\u003e\n",
              "      \u003ctd\u003e155\u003c/td\u003e\n",
              "      \u003ctd\u003e298\u003c/td\u003e\n",
              "      \u003ctd\u003e179\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e4\u003c/th\u003e\n",
              "      \u003ctd\u003e11440\u003c/td\u003e\n",
              "      \u003ctd\u003e317\u003c/td\u003e\n",
              "      \u003ctd\u003e595\u003c/td\u003e\n",
              "      \u003ctd\u003e242\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e5\u003c/th\u003e\n",
              "      \u003ctd\u003e10404\u003c/td\u003e\n",
              "      \u003ctd\u003e236\u003c/td\u003e\n",
              "      \u003ctd\u003e1221\u003c/td\u003e\n",
              "      \u003ctd\u003e178\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e6\u003c/th\u003e\n",
              "      \u003ctd\u003e5828\u003c/td\u003e\n",
              "      \u003ctd\u003e327\u003c/td\u003e\n",
              "      \u003ctd\u003e1429\u003c/td\u003e\n",
              "      \u003ctd\u003e257\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth rowspan=\"6\" valign=\"top\"\u003eSP11\u003c/th\u003e\n",
              "      \u003cth\u003e1\u003c/th\u003e\n",
              "      \u003ctd\u003e4883\u003c/td\u003e\n",
              "      \u003ctd\u003e16295\u003c/td\u003e\n",
              "      \u003ctd\u003e5545\u003c/td\u003e\n",
              "      \u003ctd\u003e5520\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e2\u003c/th\u003e\n",
              "      \u003ctd\u003e264\u003c/td\u003e\n",
              "      \u003ctd\u003e12519\u003c/td\u003e\n",
              "      \u003ctd\u003e314\u003c/td\u003e\n",
              "      \u003ctd\u003e113\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e3\u003c/th\u003e\n",
              "      \u003ctd\u003e425\u003c/td\u003e\n",
              "      \u003ctd\u003e16514\u003c/td\u003e\n",
              "      \u003ctd\u003e497\u003c/td\u003e\n",
              "      \u003ctd\u003e189\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e4\u003c/th\u003e\n",
              "      \u003ctd\u003e614\u003c/td\u003e\n",
              "      \u003ctd\u003e13933\u003c/td\u003e\n",
              "      \u003ctd\u003e1218\u003c/td\u003e\n",
              "      \u003ctd\u003e400\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e5\u003c/th\u003e\n",
              "      \u003ctd\u003e1422\u003c/td\u003e\n",
              "      \u003ctd\u003e15862\u003c/td\u003e\n",
              "      \u003ctd\u003e3143\u003c/td\u003e\n",
              "      \u003ctd\u003e839\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e6\u003c/th\u003e\n",
              "      \u003ctd\u003e2207\u003c/td\u003e\n",
              "      \u003ctd\u003e14769\u003c/td\u003e\n",
              "      \u003ctd\u003e4215\u003c/td\u003e\n",
              "      \u003ctd\u003e1333\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth rowspan=\"6\" valign=\"top\"\u003eSP12\u003c/th\u003e\n",
              "      \u003cth\u003e1\u003c/th\u003e\n",
              "      \u003ctd\u003e3003\u003c/td\u003e\n",
              "      \u003ctd\u003e2823\u003c/td\u003e\n",
              "      \u003ctd\u003e17818\u003c/td\u003e\n",
              "      \u003ctd\u003e1785\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e2\u003c/th\u003e\n",
              "      \u003ctd\u003e447\u003c/td\u003e\n",
              "      \u003ctd\u003e218\u003c/td\u003e\n",
              "      \u003ctd\u003e19335\u003c/td\u003e\n",
              "      \u003ctd\u003e178\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e3\u003c/th\u003e\n",
              "      \u003ctd\u003e1556\u003c/td\u003e\n",
              "      \u003ctd\u003e1745\u003c/td\u003e\n",
              "      \u003ctd\u003e5446\u003c/td\u003e\n",
              "      \u003ctd\u003e1227\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e4\u003c/th\u003e\n",
              "      \u003ctd\u003e1658\u003c/td\u003e\n",
              "      \u003ctd\u003e1267\u003c/td\u003e\n",
              "      \u003ctd\u003e18392\u003c/td\u003e\n",
              "      \u003ctd\u003e1094\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e5\u003c/th\u003e\n",
              "      \u003ctd\u003e2033\u003c/td\u003e\n",
              "      \u003ctd\u003e2202\u003c/td\u003e\n",
              "      \u003ctd\u003e15735\u003c/td\u003e\n",
              "      \u003ctd\u003e1627\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e6\u003c/th\u003e\n",
              "      \u003ctd\u003e1398\u003c/td\u003e\n",
              "      \u003ctd\u003e957\u003c/td\u003e\n",
              "      \u003ctd\u003e12293\u003c/td\u003e\n",
              "      \u003ctd\u003e675\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth rowspan=\"6\" valign=\"top\"\u003eSP13\u003c/th\u003e\n",
              "      \u003cth\u003e1\u003c/th\u003e\n",
              "      \u003ctd\u003e6078\u003c/td\u003e\n",
              "      \u003ctd\u003e6384\u003c/td\u003e\n",
              "      \u003ctd\u003e6886\u003c/td\u003e\n",
              "      \u003ctd\u003e13344\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e2\u003c/th\u003e\n",
              "      \u003ctd\u003e157\u003c/td\u003e\n",
              "      \u003ctd\u003e67\u003c/td\u003e\n",
              "      \u003ctd\u003e275\u003c/td\u003e\n",
              "      \u003ctd\u003e6867\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e3\u003c/th\u003e\n",
              "      \u003ctd\u003e51\u003c/td\u003e\n",
              "      \u003ctd\u003e11\u003c/td\u003e\n",
              "      \u003ctd\u003e126\u003c/td\u003e\n",
              "      \u003ctd\u003e702\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e4\u003c/th\u003e\n",
              "      \u003ctd\u003e1616\u003c/td\u003e\n",
              "      \u003ctd\u003e1548\u003c/td\u003e\n",
              "      \u003ctd\u003e2900\u003c/td\u003e\n",
              "      \u003ctd\u003e12098\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e5\u003c/th\u003e\n",
              "      \u003ctd\u003e3172\u003c/td\u003e\n",
              "      \u003ctd\u003e3536\u003c/td\u003e\n",
              "      \u003ctd\u003e5659\u003c/td\u003e\n",
              "      \u003ctd\u003e14169\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "    \u003ctr\u003e\n",
              "      \u003cth\u003e6\u003c/th\u003e\n",
              "      \u003ctd\u003e2442\u003c/td\u003e\n",
              "      \u003ctd\u003e1188\u003c/td\u003e\n",
              "      \u003ctd\u003e4550\u003c/td\u003e\n",
              "      \u003ctd\u003e4972\u003c/td\u003e\n",
              "    \u003c/tr\u003e\n",
              "  \u003c/tbody\u003e\n",
              "\u003c/table\u003e\n",
              "\u003c/div\u003e"
            ],
            "text/plain": [
              "Fd                  SP10   SP11   SP12   SP13\n",
              "aptamer exp_cycle                            \n",
              "SP10    1           6539   2096   1009    885\n",
              "        2           8833    116    347    107\n",
              "        3          11316    155    298    179\n",
              "        4          11440    317    595    242\n",
              "        5          10404    236   1221    178\n",
              "        6           5828    327   1429    257\n",
              "SP11    1           4883  16295   5545   5520\n",
              "        2            264  12519    314    113\n",
              "        3            425  16514    497    189\n",
              "        4            614  13933   1218    400\n",
              "        5           1422  15862   3143    839\n",
              "        6           2207  14769   4215   1333\n",
              "SP12    1           3003   2823  17818   1785\n",
              "        2            447    218  19335    178\n",
              "        3           1556   1745   5446   1227\n",
              "        4           1658   1267  18392   1094\n",
              "        5           2033   2202  15735   1627\n",
              "        6           1398    957  12293    675\n",
              "SP13    1           6078   6384   6886  13344\n",
              "        2            157     67    275   6867\n",
              "        3             51     11    126    702\n",
              "        4           1616   1548   2900  12098\n",
              "        5           3172   3536   5659  14169\n",
              "        6           2442   1188   4550   4972"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Drop empty foundations and produce table\n",
        "six_cycle_table_df = exp_plot_agg_df[exp_plot_agg_df.Fd != 'Foundation']  \n",
        "six_cycle_table_df.pivot(index=['aptamer', 'exp_cycle'], columns=['Fd'], \n",
        "                         values='count').astype(int)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Lik-Amwg_eLt"
      },
      "source": [
        "## Experiment Cycle, Yield Line Plot"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "KoYkSAls7DTh"
      },
      "outputs": [],
      "source": [
        "def check_n_name_match(label_str):  \n",
        "  '''Determine the number of exact matches for a particular foundation.'''\n",
        "  fd_str_list = str(label_str).split(';')\n",
        "  fd_str_list = [elem for elem in fd_str_list if 'SA' in elem or 'SP' in elem]\n",
        "  if len(fd_str_list) \u003e 0 and 'Fd' in fd_str_list[0]:\n",
        "    tag = fd_str_list[0].split('_')[-1]\n",
        "    # Get last two characters since numbers are  2-digits.\n",
        "    match_tag = '.SA'+tag[-2:]+'-'  \n",
        "    matches = []\n",
        "    for elem in fd_str_list[1:]:\n",
        "      if match_tag not in elem:\n",
        "        matches.append(0)\n",
        "      else:\n",
        "        matches.append(int(elem.split('-')[-1]))\n",
        "    n_matches = 0\n",
        "    #print (matches)\n",
        "    for i, match in enumerate(matches):\n",
        "      if i \u003c 5 and match == i+1:\n",
        "        n_matches = i+1\n",
        "      elif match == (i+1)-6:\n",
        "        n_matches = i+1\n",
        "      else:\n",
        "        return n_matches\n",
        "    return n_matches\n",
        "  \n",
        "def get_foundation_name(label_str):  \n",
        "  '''From the match string identify the foundation.'''\n",
        "  fd_str_list = str(label_str).split(';')\n",
        "  fd_str_list = [elem for elem in fd_str_list if 'SP' in elem]\n",
        "  if len(fd_str_list) \u003e 0 and 'Fd' in fd_str_list[0]:\n",
        "    tag = fd_str_list[0].split('_')[-1]\n",
        "    return tag\n",
        "  return None"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "rxGz_H_m8UqL"
      },
      "outputs": [],
      "source": [
        "def make_count_vs_cycle_line_plot(full_df):\n",
        "  fds = []\n",
        "  counts = []\n",
        "  cycles = []\n",
        "  bcs_nonzero_df = full_df[full_df['check_n_name_match'] \u003e 0]\n",
        "  for fd in full_df.base_foundation.unique():\n",
        "    temp_df = bcs_nonzero_df[(bcs_nonzero_df['base_foundation'] == fd)]\n",
        "    for i in range (1, 13): # Optional limit to check 12-cycle experiments.\n",
        "      count =  temp_df[(temp_df['check_n_name_match'] \u003e= i)]['count'].sum()\n",
        "      counts.append(count)\n",
        "      cycles.append(i)\n",
        "      fds.append(fd)\n",
        "  line_df = pd.DataFrame.from_dict({'Fd': fds, 'count': counts, \n",
        "                                    'Experimental Cycle Number': cycles})\n",
        "  line_df['Log Count'] = np.log(line_df['count']+1)\n",
        "\n",
        "  max_cycles = max(line_df[line_df['count'] \u003e 0]['Experimental Cycle Number'])\n",
        "  plt.figure(figsize=(float(max_cycles) / 2., 6))\n",
        "  sns.lineplot(data=line_df[line_df['Experimental Cycle Number'] \u003c= max_cycles], \n",
        "               x='Experimental Cycle Number', y='Log Count', hue='Fd')\n",
        "  plt.legend()\n",
        "  return line_df"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "height": 388
        },
        "executionInfo": {
          "elapsed": 3986,
          "status": "ok",
          "timestamp": 1632439448761,
          "user": {
            "displayName": "",
            "photoUrl": "",
            "userId": ""
          },
          "user_tz": 420
        },
        "id": "TZ1Dxm6xq09d",
        "outputId": "80c61a64-c923-48b7-830d-6f2ca3c07ff7"
      },
      "outputs": [
        {
          "data": {
            "image/png": "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\nHZRUXVwtfXMAAAAASUVORK5CYII=\n",
            "text/plain": [
              "\u003cFigure size 300x600 with 1 Axes\u003e"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# Note the affect of the random number generator variance is most apparent in\n",
        "# the low counts of the last cycle in the line plot figure below. \n",
        "full_df['base_foundation'] = full_df.ordered_foundation_labels.apply(get_foundation_name)\n",
        "full_df['check_n_name_match'] = full_df.ordered_foundation_labels.apply(check_n_name_match)\n",
        "_ = make_count_vs_cycle_line_plot(full_df)"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "collapsed_sections": [],
      "last_runtime": {
        "build_target": "//research/biology/collaborations/aptamers:notebook",
        "kind": "shared"
      },
      "name": "BCS ProtSeq 6 Cycle Data Set.ipynb",
      "provenance": [
        {
          "file_id": "1Q0YxXEfS56FhqHGZZUnGj3ALT5X6Mc0B",
          "timestamp": 1632432735326
        },
        {
          "file_id": "1JKB4cfTBGAA_G7VGD8JyWV4-2Abvrb6R",
          "timestamp": 1632269031835
        },
        {
          "file_id": "1cb2VRGK_z0qq0mUlxXKdCfuXBs4M1iP3",
          "timestamp": 1632263844965
        },
        {
          "file_id": "1fONwpc7if6IkMxFexvXvYkFqv1FB5NaG",
          "timestamp": 1631737568145
        },
        {
          "file_id": "1ZlC9Jz_Zaw5TCS7AuD_yxQDG4sQD9Jtd",
          "timestamp": 1631720954129
        }
      ]
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
